package com.voltmao.service.application.doc;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.voltmao.persistent.mapper.DocApplyAuditMapper;
import com.voltmao.persistent.mapper.DocApplyMapper;
import com.voltmao.persistent.mapper.DocApplyMapsMapper;
import com.voltmao.persistent.mapper.DocDbMapper;
import com.voltmao.persistent.model.*;
import com.voltmao.service.application.sys.MessageTemplateServiceImpl;
import com.voltmao.webpro.frame.dto.DataPage;
import com.voltmao.webpro.utils.PropertiesUtils;
import com.voltmao.webpro.utils.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 资料申请管理服务接口
 *
 * @author zhanglin
 * @date 2018/04/15
 */
@Service
public class ApplyServiceImpl {
    private static final Logger testLogger = LoggerFactory.getLogger("MY_TEST_LOGGER");

    @Autowired
    DocApplyMapper docApplyMapper;
    @Autowired
    DocApplyMapsMapper docApplyMapsMapper;
    @Autowired
    DocApplyAuditMapper docApplyAuditMapper;
    @Autowired
    MessageTemplateServiceImpl messageTemplateService;
    @Autowired
    DocDbMapper docDbMapper;

    /**
     * 以apply为主表查询
     * @param params 查询参数
     * @return DataPage集合
     */
    public DataPage selectApplyDataPage(Map<String,Object> params){
        testLogger.info("带查询参数："+params.toString());
        System.out.println("带查询参数："+params.toString());
        DataPage dataPage = new DataPage();
        int pageIndex = StringUtils.parseInt(params.get("pageNumber")+"", 1);
        int pageSize = StringUtils.parseInt(params.get("pageSize")+"", 20);

        DocApplyCriteria example = new DocApplyCriteria();
        DocApplyCriteria.Criteria c = example.createCriteria();
        example.setPageSize(pageSize);
        example.setLimitStart((pageIndex - 1) * pageSize);
        example.setOrderByClause("doc_apply.create_date desc");
        c.andIsDelEqualTo(0);
        if(params.size() > 0) {
            String dataId = "dataId";
            if (StringUtils.isNotEmpty(params.get(dataId))) {
                //申请表id查询
                c.andDataIdEqualTo(params.get(dataId) + "");
            }
            String forCorpEmployesUser = "forCorpEmployesUser";
            if (StringUtils.isNotEmpty(params.get(forCorpEmployesUser))) {
                //操作人id查询
                c.andForCorpEmployesUserEqualTo(params.get(forCorpEmployesUser) + "");
            }
            String forProviderUser = "forProviderUser";
            if (StringUtils.isNotEmpty(params.get(forProviderUser))) {
                //渠道商id查询
                c.andForProviderUserEqualTo(params.get(forProviderUser) + "");
            }
            String applyReason = "applyReason";
            if (StringUtils.isNotEmpty(params.get(applyReason))) {
                //申请理由模糊查询
                c.andApplyReasonLike("%" + params.get(applyReason) + "%");
            }
        }
        String auditType = "auditType";
        if(StringUtils.isNotEmpty(params.get(auditType))) {
            //按照审核状态类型查询0,1,2
            example.setAuditType(params.get(auditType)+"");
        }
        String auditUser = "auditUser";
        if(StringUtils.isNotEmpty(params.get(auditUser))) {
            //按照审核人id查询
            example.setAuditType(params.get(auditUser)+"");
        }
        String providerName = "providerName";
        if(StringUtils.isNotEmpty(params.get(providerName))) {
            //按照渠道商名称模糊查询
            example.setProviderName(params.get(providerName)+"");
        }
        List<Map<String, Object>> results = docApplyMapper.selectMapByExample(example);
        //所有未被删除的申请资料,某些项进行转换
        List<Map<String, Object>> oldLists =  docApplyMapsMapper.selectByApplyId(null,"0");
        for(Map<String, Object> tmpMap:results){
            String applyId =tmpMap.get("dataId")+"";
            List<Map<String, Object>> items = oldLists.stream()
                    .filter(item->applyId.equals(item.get("forDocApply")+""))
                    .collect(Collectors.toList());
            tmpMap.put("docs", items);
        }
        dataPage.pageindex= pageIndex;
        dataPage.pagesize = pageSize;
        dataPage.rows = results;
        dataPage.total = docApplyMapper.countByExample(example);
        return dataPage;
    }

    public DataPage getDocs(Map<String,Object> params) {
        testLogger.info("带查询参数："+params.toString());
        System.out.println("带查询参数："+params.toString());
        DataPage dataPage = new DataPage();
        int pageIndex = StringUtils.parseInt(params.get("pageNumber")+"", 1);
        int pageSize = StringUtils.parseInt(params.get("pageSize")+"", 20);

        String providerId = params.get("providerId")+"";
        if(StringUtils.isEmpty(providerId)){
            providerId = null;
        }
        String docName = params.get("docName")+"";
        if(StringUtils.isEmpty(docName)){
            docName = null;
        }
        String docType = params.get("docType")+"";
        if(StringUtils.isEmpty(docType)){
            docType = null;
        }
        List<Map<String, Object>> lists = docDbMapper.getApplyDocs(providerId, docName, (pageIndex - 1) * pageSize, pageSize, docType);
        dataPage.pageindex= pageIndex;
        dataPage.pagesize = pageSize;
        dataPage.rows = lists;
        dataPage.total = docDbMapper.countApplyDocs(providerId, docName, docType);
        return dataPage;
    }

    /**
     * 获取待审核申请数量
     * @return 数量
     */
    public int countToBeAudit(){
        return docApplyMapper.countToBeAudit();
    }
    /**
     * 资料申请新增或修改为主表，具体资料（1对n）maps写入
     * @param params 新增或修改参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertOrUpdateApply(Map<String, Object> params){
        testLogger.info("新增或修改参数："+params.toString());
        System.out.println("新增或修改参数："+params.toString());
        String toId =  "a2c17488-37b9-11e8-b549-00163e069ea3";
        String insert = "INSERT";
        String update = "UPDATE";
        String flag = params.get("flag")+"";
        String docApplyId = StringUtils.uuid36();
        if(insert.equals(flag)) {
            //新增资料申请记录
            JSONObject tmpApply = JSONObject.parseObject(params.get("apply")+"");
            DocApply docApply = (DocApply) PropertiesUtils.mapToObject(tmpApply, DocApply.class);
            docApply.setCreateDate(new Date());
            docApply.setDataId(docApplyId);
            docApply.setIsDel(0);
            docApplyMapper.insert(docApply);
            //添加资料审核表
            DocApplyAudit docAudit = new DocApplyAudit();
            docAudit.setDataId(StringUtils.uuid36());
            docAudit.setForDirZlshzt("0");
            docAudit.setForDocApply(docApplyId);
            docApplyAuditMapper.insert(docAudit);
            //新增资料申请资料记录表
            JSONArray array = JSONArray.parseArray(StringUtils.splitArray(params.get("maps")+""));
            if(StringUtils.isNotEmpty(array) && array.size() > 0){
                for(int i=0;i<array.size();i++){
                    JSONObject tmpObj = array.getJSONObject(i);
                    DocApplyMaps docMap = (DocApplyMaps)PropertiesUtils.mapToObject(tmpObj, DocApplyMaps.class);
                    docMap.setDataId(StringUtils.uuid36());
                    docMap.setForDicZlzszt("0");
                    docMap.setCreateDate(new Date());
                    docMap.setForDocApply(docApplyId);
                    docMap.setIsDel(0);
                    docApplyMapsMapper.insert(docMap);
                }
            }
            //发送消息
            String fromId = docApply.getForCorpEmployesUser();
            String providerId = docApply.getForProviderUser();
            messageTemplateService.docApply(fromId, toId, providerId);
        }
        if(update.equals(flag)){
            //修改
            String updateApplyId =  params.get("dataId")+"";
            boolean isSelf = true;
            DocApply docApply = docApplyMapper.selectByPrimaryKey(updateApplyId);
            if(!StringUtils.isNotEmpty(docApply)){
                throw new NullPointerException("数据库不存在该项申请");
            }
            String applyReason = "applyReason";
            if(StringUtils.isNotEmpty(params.get(applyReason))) {
                docApply.setApplyReason(params.get(applyReason)+"");
                docApplyMapper.updateByPrimaryKeySelective(docApply);
            }
            //修改审核表
            String zlshzt = "zlshzt";
            if(StringUtils.isNotEmpty(params.get(zlshzt))){
                isSelf = false;
                DocApplyAudit docApplyAudit = docApplyAuditMapper.selectByapplyId(updateApplyId);
                docApplyAudit.setForDirZlshzt(params.get(zlshzt)+"");
                docApplyAudit.setForCorpEmployesUser(params.get("auditUser")+"");
                docApplyAudit.setAuditReason(params.get("reason")+"");
                docApplyAuditMapper.updateByPrimaryKey(docApplyAudit);
            }
            List<Map<String, Object>> oldLists =  docApplyMapsMapper.selectByApplyId(updateApplyId,"0");
            String maps = "maps";
            if(StringUtils.isNotEmpty(params.get(maps))){
                JSONArray array = JSONArray.parseArray(StringUtils.splitArray(params.get(maps)+""));
                update(oldLists, array, isSelf, updateApplyId);
            }
            String fromId = docApply.getForCorpEmployesUser();
            String providerId = docApply.getForProviderUser();
            if(isSelf){
                //发送消息
                messageTemplateService.docUpdate(fromId, toId, providerId);
            } else {
                //发送消息
                boolean isPass = false;
                if("1".equals(params.get(zlshzt)+"")){
                    isPass = true;
                }
                if("2".equals(params.get(zlshzt)+"")){
                    isPass = false;
                }
                messageTemplateService.docAudit(toId,fromId,providerId,isPass);
            }
        }
    }


    /**
     * 将oldLists和array对比，执行操作
     * 是否是自己操作（市场人员）
     * @param oldLists 数据库的记录
     * @param array 新提交的记录
     * @param isSelf 是否是市场人员本身
     * @param applyId 申请表id
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(List<Map<String, Object>> oldLists, JSONArray array, boolean isSelf, String applyId){
        testLogger.info("旧数据："+oldLists.toString());
        testLogger.info("新数据："+array.toJSONString());
        testLogger.info("isSelf："+isSelf+"; 申请表主键："+applyId);
        System.out.println("旧数据："+oldLists.toString()+"||"+"新数据："+array.toJSONString()+"||"+"isSelf："+isSelf+"; 申请表主键："+applyId);
        if(StringUtils.isNotEmpty(array) && array.size() > 0){
            for(int i=0;i<array.size();i++){
                JSONObject tmpObj = array.getJSONObject(i);
                String tmpId = tmpObj.get("forCorpDocDb")+"";
                List<Map<String, Object>> itemList = oldLists.stream().filter(item->tmpId.equals(item.get("forCorpDocDb")+"")).collect(Collectors.toList());
                if(itemList == null || itemList.size() == 0){
                    //新增
                    DocApplyMaps docMap = (DocApplyMaps)PropertiesUtils.mapToObject(tmpObj, DocApplyMaps.class);
                    docMap.setDataId(StringUtils.uuid36());
                    if(isSelf) {
                        docMap.setForDicZlzszt("0");
                    } else{
                        docMap.setForDicZlzszt("1");
                    }
                    docMap.setCreateDate(new Date());
                    docMap.setForDocApply(applyId);
                    docMap.setIsDel(0);
                    docApplyMapsMapper.insert(docMap);
                } else{
                    //不变的
                    for(int j=0;j<oldLists.size();j++){
                        if(tmpId.equals(oldLists.get(j).get("forCorpDocDb")+"")){
                            oldLists.remove(j);
                        }
                    }
                }
            }
        }
        //将留下的删除
        for(Map<String, Object> item:oldLists){
            DocApplyMaps tmpMaps = (DocApplyMaps) PropertiesUtils.mapToObject(item, DocApplyMaps.class);
            if(isSelf) {
                tmpMaps.setIsDel(1);
            } else {
                tmpMaps.setForDicZlzszt("2");
            }
            tmpMaps.setUpdateDate(new Date());
            docApplyMapsMapper.updateByPrimaryKeySelective(tmpMaps);
        }
    }

    /**
     * 删除申请表apply和对应的maps
     * 审核表没有删除字段，暂不处理
     * 提供apply主键进行删除
     * @param dataId 申请表id
     * @return 删除条数
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteApply(String dataId){
        testLogger.info("待删除申请主键："+dataId);
        System.out.println("待删除申请主键："+dataId);
        if(!StringUtils.isEmpty(dataId)){
            DocApply docApply = docApplyMapper.selectByPrimaryKey(dataId);
            docApply.setUpdateDate(new Date());
            docApply.setIsDel(1);
            DocApplyAudit daAudit = docApplyAuditMapper.selectByapplyId(dataId);
            String noDelete = "1";
            if(daAudit.getForDirZlshzt().equals(noDelete)){
                throw new IllegalStateException("禁止删除");
            }
            //删除maps
            List<Map<String, Object>> caMaps =  docApplyMapsMapper.selectByApplyId(dataId,"0");
            for(Map<String, Object> item:caMaps){
                DocApplyMaps tmpMaps = (DocApplyMaps) PropertiesUtils.mapToObject(item, DocApplyMaps.class);
                tmpMaps.setIsDel(1);
                tmpMaps.setUpdateDate(new Date());
                docApplyMapsMapper.updateByPrimaryKeySelective(tmpMaps);
            }
            return docApplyMapper.updateByPrimaryKey(docApply);
        } else {
            throw new NullPointerException("主键不存在");
        }
    }
}
